import useMemberStore from "@/store/member";
import { isArray } from "lodash-es";
import { App, Directive, DirectiveBinding } from "vue";

const hasAllPermissions = (needPermissions: string[], userPermissions: string[]): boolean => {
  return needPermissions.every((permission) => userPermissions.includes(permission));
};

const hasOneOfPermission = (needPermissions: string[], userPermissions: string[]): boolean => {
  return needPermissions.some((permission) => userPermissions.includes(permission));
};

const vAuth: Directive = {
  beforeMount: (el: HTMLElement) => {
    el.parentNode?.removeChild(el);
  },

  // TODO: mounted 钩子或许有更好的写法
  mounted: (el: HTMLElement, binding: DirectiveBinding<string | string[]>) => {
    const { value, modifiers } = binding;
    const { getMemberPermissions } = storeToRefs(useMemberStore());
    const parent = el.parentNode;

    watch(
      () => getMemberPermissions.value,
      () => {
        if (!value) {
          parent?.removeChild(el);
        }

        if (isArray(value)) {
          // 如果没有使用 oneof 修饰符，则默认是要拥有全部的权限
          if (!modifiers.oneof && hasAllPermissions(value, getMemberPermissions.value)) {
            parent?.appendChild(el);
          } else if (modifiers.oneof && hasOneOfPermission(value, getMemberPermissions.value)) {
            parent?.appendChild(el);
          } else {
            parent?.removeChild(el);
          }
        } else {
          if (getMemberPermissions.value.includes(value)) {
            parent?.appendChild(el);
          } else {
            parent?.removeChild(el);
          }
        }
      },
      {
        immediate: true,
        deep: true,
      }
    );
  },
};

export function setupAuthDirective(app: App) {
  app.directive("auth", vAuth);
}

export default vAuth;
